/*
* ContextMenu - jQuery plugin for right-click context menus
*
* Author: Chris Domigan
* Contributors: Dan G. Switzer, II
* Parts of this plugin are inspired by Joern Zaefferer's Tooltip plugin
*
* Dual licensed under the MIT and GPL licenses:
*   http://www.opensource.org/licenses/mit-license.php
*   http://www.gnu.org/licenses/gpl.html
*
* Version: r2
* Date: 16 July 2007
*
* For documentation visit http://www.trendskitchens.co.nz/jquery/contextmenu/
*
*/

(function($) {
    var shown = false, setWindow = false;
    var menu, shadow, trigger, content, hash, currentTarget;
    var defaults = {
        menuCssClass: 'contextmenu',
        itemCssClass: 'contextmenuitem',
        itemHoverCssClass: 'contextmenuitemhover',
        headerCssClass: 'contextmenuheader',
        footerCssClass: 'contextmenufooter',
        eventPosX: 'pageX',
        eventPosY: 'pageY',
        shadow: false,
        onContextMenu: null,
        onShowMenu: null
    };

    $.fn.contextMenu = function(id, options) {
        if (!menu) {                                      // Create singleton menu
            menu = $('<div id="jqContextMenu"></div>')
               .hide()
               .css({ position: 'absolute',
                   zIndex: '50000'
               })
               .appendTo('body')
               .bind('click', function(e) {
                   e.stopPropagation();
               })
               .bind('contextmenu', function(e) {
                   e.preventDefault();
                   return false;
               });
        }
        if (!shadow) {
            shadow = $('<div></div>')
                 .css({ backgroundColor: '#000', position: 'absolute', opacity: 0.2, zIndex: 49999 })
                 .appendTo('body')
                 .hide();
        }
        hash = hash || [];
        hash.push({
            id: id,
            menuStyle: $.extend({}, defaults.menuStyle, options.menuStyle || {}),
            itemStyle: $.extend({}, defaults.itemStyle, options.itemStyle || {}),
            itemHoverStyle: $.extend({}, defaults.itemHoverStyle, options.itemHoverStyle || {}),
            menuCssClass: options.menuCssClass || defaults.menuCssClass,
            itemCssClass: options.itemCssClass || defaults.itemCssClass,
            itemHoverCssClass: options.itemHoverCssClass || defaults.itemHoverCssClass,
            headerCssClass: options.headerCssClass || defaults.headerCssClass,
            footerCssClass: options.footerCssClass || defaults.footerCssClass,
            bindings: options.bindings || {},
            shadow: options.shadow || options.shadow === false ? options.shadow : defaults.shadow,
            onContextMenu: options.onContextMenu || defaults.onContextMenu,
            onShowMenu: options.onShowMenu || defaults.onShowMenu,
            eventPosX: options.eventPosX || defaults.eventPosX,
            eventPosY: options.eventPosY || defaults.eventPosY
        });

        var index = hash.length - 1;
        var bindevent;
        //		alert(navigator.appVersion);
        if (/Mobile|Android|Tablet|iPad/i.test(navigator.appVersion)) {
            bindevent = 'click'; //safari on iPad has no contextmenu;
        } else {
            bindevent = 'contextmenu';
        }

        $(this).bind(bindevent, function(e) {
            // Check if onContextMenu() defined
            var args = {};
            var bShowContext = (!!hash[index].onContextMenu) ? hash[index].onContextMenu(e, args) : true;
            if (bShowContext) display(index, this, e, options, args);
            return false;
        });
        if (!setWindow) {
            var win = window;
            while (true) {
                $(win).bind('mousedown', function(event) {
                    if (shown && !$(event.target).parents("#jqContextMenu>.contextmenu").length) {
                        hide();
                    }
                });
                $(window.document).bind('mousedown', function (event) {
                    if (shown && !$(event.target).parents("#jqContextMenu>.contextmenu").length) {
                        hide();
                    }
                });
                if (win.parent == win) {
                    break;
                } else {
                    win = win.parent;
                }
            }
            setWindow = true;
        }
        return this;
    };

    function display(index, trigger, e, options, args) {
        var cur = hash[index];
        content = $('#' + cur.id).find('ul:first').clone(true);
        //		content.css(cur.menuStyle).find('li').css(cur.itemStyle).hover(
        //      function() {
        //      	$(this).css(cur.itemHoverStyle);
        //      },
        //      function() {
        //      	$(this).css(cur.itemStyle);
        //      }
        content.addClass(cur.menuCssClass).find('li').addClass(cur.itemCssClass).hover(
		function() { $(this).addClass(cur.itemHoverCssClass) },
		function() { $(this).removeClass(cur.itemHoverCssClass) }
    ).find('img').css({ verticalAlign: 'middle', paddingRight: '2px' });

        // Send the content to the menu
        menu.html(content);
        $("<div></div>").prependTo(menu).addClass(cur.headerCssClass);
        $("<div></div>").appendTo(menu).addClass(cur.footerCssClass);

        // if there's an onShowMenu, run it now -- must run after content has been added
        // if you try to alter the content variable before the menu.html(), IE6 has issues
        // updating the content
        if (!!cur.onShowMenu) menu = cur.onShowMenu(e, menu, args);

        $.each(cur.bindings, function(id, func) {
            $('#' + id, menu).bind('click', function(e) {
                hide();
                func(trigger, currentTarget, args);
            });
        });

        //menu.css({ 'left': e[cur.eventPosX], 'top': e[cur.eventPosY] }).show();
        //if (cur.shadow) shadow.css({ width: menu.width(), height: menu.height(), left: e.pageX + 2, top: e.pageY + 2 }).show();
        menu.css({ 'left': (e[cur.eventPosX] + menu.width() < document.body.clientWidth) ? e[cur.eventPosX] : e[cur.eventPosX] - menu.width(),
            'top': (e[cur.eventPosY] + menu.height() < document.body.clientHeight) ? e[cur.eventPosY] : Math.max(e[cur.eventPosY] - menu.height(), 0)
        }).show();
        if (cur.shadow) {
            shadow.css({
                width: menu.width(),
                height: menu.height(),
                left: (e.pageX > menu.width()) ? e.pageX - menu.width() / 2 : e.pageX + 2,
                top: (e.pageY > menu.height()) ? e.pageY - menu.height() : e.pageY + 2
            }).show();
        }
        shown = true;

        // Show Events
        if ($.contextMenu.showEvents) {
            for (var i = 0; i < $.contextMenu.showEvents.length; i++) {
                if ($.contextMenu.showEvents[i] && typeof ($.contextMenu.showEvents[i]) == 'function') {
                    $.contextMenu.showEvents[i].call(this);
                }
            }
        }
    }

    function hide() {
        menu.hide();
        shadow.hide();
        shown = false;

        // Hide Events
        if ($.contextMenu.hideEvents) {
            for (var i = 0; i < $.contextMenu.hideEvents.length; i++) {
                if ($.contextMenu.hideEvents[i] && typeof ($.contextMenu.hideEvents[i]) == 'function') {
                    $.contextMenu.hideEvents[i].call(this);
                }
            }
        }
    }

    // Apply defaults
    $.contextMenu = {
        defaults: function(userDefaults) {
            $.each(userDefaults, function(i, val) {
                if (typeof val == 'object' && defaults[i]) {
                    $.extend(defaults[i], val);
                }
                else defaults[i] = val;
            });
        },
        showEvents: [],
        hideEvents: []
    };

})(jQuery);

$(function() {
    $('div.contextMenu').hide();
});